#!/usr/bin/env python

#########################################################################
# Author: Kai Ren
# Created Time: 2012-02-13 19:10:12
# File Name: ./encoder.py
# Description:
#########################################################################

import struct
import array
import string
import numpy as np

from util import *
from final_enc import FinalEncoder

class Query:
    def __init__(self, filenames):
        pass

    def get_rdata(self, metricname, start, end):
        data = np.load('../data/%s.npy'%(metricname))
        arr_data = array.array('f', data)
        return arr_data.tostring()

    #Range query on a particular metric
    def get_data(self, metricname, start, end):
#        lindex = self.get_index(start)
#        rindex = self.get_index(end)
#        retdata = self._data[metricname][lindex:rindex+1]
#        return self.encode([1, 6, 6, 6, 6])
        f = open('../data/%s.cz'%(metricname), 'rb')
        data = f.readline()
        f.close()
        return data

    def encode(self, data):
        Enc = FinalEncoder()
        
        retdata = Enc.enc(data)
        print repr(data) == repr(Enc.dec(retdata))
        retstr = []
        print "initial", retdata[0]
        print "symcode", retdata[1]
        print "lencode", retdata[2]
        print "totalsym", retdata[3]
        retstr  = struct.pack('f', float(retdata[0]))
        retstr += self.marshal_dict(retdata[1], 1)
        retstr += self.marshal_dict(retdata[2], 0)
        retstr += struct.pack('=L', retdata[3])
        retstr += retdata[4].tostring()
        print "# bits/datapoint=", 8.0 * len(retdata[4]) / retdata[3]
        return retstr

    def get_index(self, time_stamp):
        return 20

    def marshal_dict(self, mdict, mtype):
        #print mdict, mtype, len(mdict.keys())
        keys = sorted(mdict.keys())
        retstr = struct.pack('=L', len(keys))
        for k in keys:
            retstr += struct.pack('=L', len(k))
            retstr += array.array('B', k).tostring()
            if mtype == 0:
                if mdict[k] == '\x00':
                    val = 0xfffffff
                else:
                    val = int(mdict[k])
                retstr += struct.pack('=L', val)
            else:
                if mdict[k] == '\x00':
                    val = float('inf')
                else:
                    val = float(mdict[k])
                retstr += struct.pack('f', val)
        return retstr

if __name__ == '__main__':
    query = Query('')
    metric_list = [ 'humidity', 'tempc', 'pressure']
    for metric in metric_list:
        print metric
        rawdata = np.load('./data/%s.npy'%(metric))
        
        data = []
        prev = 0
        for d in rawdata[:2048]:
            data.append(str(d-prev))
            prev = d
            
        cnt = sym_cnt(data)
        print "# datapoints=", len(data)
        print "# syms=", len(cnt)
        print "entropy=", entropy(cnt)
            
        coded = query.encode(data)
        
        f = open('./node.js-server/%s.cz'%(metric), 'wb')
        
        f.write(coded)
        f.close()
